using System;
using System.Collections.Generic;
using System.Net;
using GameFramework;
using GameFramework.Event;
using GameFramework.Network;
using UnityEngine;
using UnityGameFramework.Runtime;

namespace StarForce
{
    public sealed partial class GateComponent : GameFrameworkComponent
    {
        public const string ChannelName = "Gate";

        [SerializeField] private string m_IP = "127.0.0.1";

        private IPAddress m_IPAddress = IPAddress.Any;

        [SerializeField] private int m_Port = 10001;

        [SerializeField] private float m_HeartBeatInterval = 5f;

        [SerializeField] private bool m_ResetHeartBeatElapseSecondsWhenReceivePacket = true;

        private string m_UID;

        private string m_ServerId;

        private bool m_StarCheck;

        public bool StarCheck
        {
            get { return m_StarCheck; }
            set { m_StarCheck = value; }
        }

        public string Uid
        {
            get { return m_UID; }
            set { m_UID = value; }
        }

        public string ServerId
        {
            get { return m_ServerId; }
            set { m_ServerId = value; }
        }

        private INetworkChannel m_NetworkChannel = null;

        private INetworkManager m_NetworkManager = null;

        private INetworkChannelHelper m_NetworkChannelHelper = null;

        private GameFrameworkAction<INetworkChannel, object> m_OnConnected;

        private GameFrameworkAction<INetworkChannel> m_OnClosed;

        /// <summary>
        /// 当连接Gate服务器成功事件。
        /// </summary>
        public event GameFrameworkAction<INetworkChannel, object> OnConnected
        {
            add { m_OnConnected += value; }
            remove { m_OnConnected -= value; }
        }

        /// <summary>
        /// 当断开Gate服务器成功事件。
        /// </summary>
        public event GameFrameworkAction<INetworkChannel> OnClosed
        {
            add { m_OnClosed += value; }
            remove { m_OnClosed -= value; }
        }

        /// <summary>
        /// 服务器IPV4地址。
        /// </summary>
        public IPAddress IAddress
        {
            get { return m_IPAddress; }
        }

        /// <summary>
        /// 服务器连接端口。
        /// </summary>
        public int Port
        {
            get { return m_Port; }
            set { m_Port = value; }
        }


        public string Ip
        {
            get { return m_IP; }
            set
            {
                m_IP = value;
                m_IPAddress = IPAddress.Parse(m_IP);
            }
        }

        /// <summary>
        /// 网络连接通道。
        /// </summary>
        public INetworkChannel NetworkChannel
        {
            get { return m_NetworkChannel; }
        }

        /// <summary>
        /// 获取网络频道名称。
        /// </summary>
        public string Name
        {
            get { return m_NetworkChannel.Name; }
        }

        /// <summary>
        /// 获取是否已连接。
        /// </summary>
        public bool Connected
        {
            get { return m_NetworkChannel.Connected; }
        }

        /// <summary>
        /// 获取网络服务类型。
        /// </summary>
        public ServiceType ServiceType
        {
            get { return m_NetworkChannel.ServiceType; }
        }

        /// <summary>
        /// 获取网络地址类型。
        /// </summary>
        public AddressFamily AddressFamily
        {
            get { return m_NetworkChannel.AddressFamily; }
        }

        /// <summary>
        /// 获取要发送的消息包数量。
        /// </summary>
        public int SendPacketCount
        {
            get { return m_NetworkChannel.SendPacketCount; }
        }

        /// <summary>
        /// 获取累计发送的消息包数量。
        /// </summary>
        public int SentPacketCount
        {
            get { return m_NetworkChannel.SentPacketCount; }
        }

        /// <summary>
        /// 获取已接收未处理的消息包数量。
        /// </summary>
        public int ReceivePacketCount
        {
            get { return m_NetworkChannel.ReceivePacketCount; }
        }

        /// <summary>
        /// 获取累计已接收的消息包数量。
        /// </summary>
        public int ReceivedPacketCount
        {
            get { return m_NetworkChannel.ReceivedPacketCount; }
        }

        /// <summary>
        /// 获取或设置当收到消息包时是否重置心跳流逝时间。
        /// </summary>
        public bool ResetHeartBeatElapseSecondsWhenReceivePacket
        {
            get { return m_NetworkChannel.ResetHeartBeatElapseSecondsWhenReceivePacket; }
            set
            {
                m_NetworkChannel.ResetHeartBeatElapseSecondsWhenReceivePacket =
                    m_ResetHeartBeatElapseSecondsWhenReceivePacket = value;
            }
        }

        /// <summary>
        /// 获取丢失心跳的次数。
        /// </summary>
        public int MissHeartBeatCount
        {
            get { return m_NetworkChannel.MissHeartBeatCount; }
        }

        /// <summary>
        /// 获取或设置心跳间隔时长，以秒为单位。
        /// </summary>
        public float HeartBeatInterval
        {
            get { return m_NetworkChannel.HeartBeatInterval; }
            set { m_NetworkChannel.HeartBeatInterval = m_HeartBeatInterval = value; }
        }

        /// <summary>
        /// 获取心跳等待时长，以秒为单位。
        /// </summary>
        public float HeartBeatElapseSeconds
        {
            get { return m_NetworkChannel.HeartBeatElapseSeconds; }
        }


        private int m_ConnectData = 0;

        /// <summary>
        /// 游戏框架组件初始化。
        /// </summary>
        protected override void Awake()
        {
            base.Awake();

            m_NetworkManager = GameFrameworkEntry.GetModule<INetworkManager>();

            if (m_NetworkManager == null)
            {
                Log.Fatal("Network manager is invalid.");

                return;
            }
        }

        private void Start()
        {
            m_StarCheck = false;
            m_IPAddress = IPAddress.Parse(m_IP);
            m_ConnectData = 0;
            m_NetworkChannelHelper = new DemoNetworkChannelHelper();
            m_NetworkChannel =
                m_NetworkManager.CreateNetworkChannel(ChannelName, ServiceType.Tcp, m_NetworkChannelHelper);
            m_NetworkChannel.HeartBeatInterval = m_HeartBeatInterval;
            m_NetworkChannel.ResetHeartBeatElapseSecondsWhenReceivePacket =
                m_ResetHeartBeatElapseSecondsWhenReceivePacket;

            GameEntry.Event.Subscribe(UnityGameFramework.Runtime.NetworkConnectedEventArgs.EventId, OnNetworkConnected);
            GameEntry.Event.Subscribe(UnityGameFramework.Runtime.NetworkClosedEventArgs.EventId, OnNetworkClosed);
//            GameEntry.Event.Subscribe(WebRequestSuccessEventArgs.EventId, RequestSuccessEvent);
        }

        private void Update()
        {
            if (!m_NetworkChannel.Connected)
            {
                //todo 弹出重连的框
            }
        }

        private void OnNetworkConnected(object sender, GameEventArgs e)
        {
            UnityGameFramework.Runtime.NetworkConnectedEventArgs ne =
                (UnityGameFramework.Runtime.NetworkConnectedEventArgs) e;

            if (ne.NetworkChannel != m_NetworkChannel)
            {
                return;
            }

            if (m_OnConnected != null)
            {
                m_OnConnected(m_NetworkChannel, ne.UserData);
            }
        }

        private void OnNetworkClosed(object sender, GameEventArgs e)
        {
            UnityGameFramework.Runtime.NetworkClosedEventArgs
                ne = (UnityGameFramework.Runtime.NetworkClosedEventArgs) e;

            if (ne.NetworkChannel != m_NetworkChannel)
            {
                return;
            }

            if (m_OnClosed != null)
            {
                m_OnClosed(m_NetworkChannel);
            }
        }


        /// <summary>
        /// 设置默认事件处理函数。
        /// </summary>
        /// <param name="handler">要设置的默认事件处理函数。</param>
        public void SetDefaultHandler(EventHandler<Packet> handler)
        {
            m_NetworkChannel.SetDefaultHandler(handler);
        }

        /// <summary>
        /// 连接到远程主机。
        /// </summary>
        public void Connect()
        {
            Connect(null);
        }

        /// <summary>
        /// 连接到远程主机。
        /// </summary>
        /// <param name="userData">用户自定义数据。</param>
        public void Connect(object userData)
        {
            m_NetworkChannel.Connect(m_IPAddress, m_Port, userData);
        }


        /// <summary>
        /// 连接到分配的地址
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        /// <param name="userData"></param>
        public void ConnectAllocation(string ip, string port, object userData)
        {
            m_NetworkChannel.Close();
            m_NetworkChannel.Connect(IPAddress.Parse(ip), Int32.Parse(port), userData);
        }

        /// <summary>
        /// 关闭网络频道。
        /// </summary>
        public void Close()
        {
            m_NetworkChannel.Close();
        }

        /// <summary>
        /// 向远程主机发送消息包。
        /// </summary>
        /// <typeparam name="T">消息包类型。</typeparam>
        /// <param name="packet">要发送的消息包。</param>
        public void Send<T>(T packet) where T : Packet
        {
            m_NetworkChannel.Send<T>(packet);
        }
        private void OnApplicationPause(bool focus)
        {
            if (!m_StarCheck)
            {
                return;
            }

            //进入程序状态更改为前台
            if (focus)
            {
                Log.Info("程序进入后台");
            }
            else
            {
                //离开程序进入到后台状态
                Log.Info("程序进入前台");
                if (!Connected)
                {
//                    Reconnect();
                }
            }
        }
    }
}

